Rename JSON mode → Chat, promote it as a first-class Claude interface - #82
Merged
Conversation
…n user-facing strings Promotes the React-chat interface from its experimental name. The internal identifiers (`json-claude` tab type, `JsonModeChat` component, `jsonClaude/*` events, `defaultClaudeTabType: 'xterm' | 'json'` field, `json-mode-cards/` directory, `plans/json-mode-native-chat.md`, etc.) all stay unchanged — only display strings shift. User-visible changes: - Tab labels: `Claude (JSON)` → `Chat` - Right-click menu (desktop + mobile): `Convert to JSON-mode chat` → `Switch to Chat`; `Convert to terminal mode` → `Switch to Terminal` - Sparkles tooltip: `New Claude (JSON) tab` → `New Chat tab`; `⇧-click for Claude (JSON, experimental)` → `⇧-click for Chat`; `⇧-click for Claude Code (xterm)` → `⇧-click for Terminal` - ActivityCosts empty-state copy - CLAUDE.md / CONTRIBUTING.md user-facing phrasing Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… + tab header Makes the Chat-vs-Terminal interface choice well-placed and discoverable without changing the default (Terminal stays default for new installs). Settings restructure: - Removes the standalone `Experimental → JSON-mode Claude tabs` sub-card. The Interface picker (Terminal/Chat radio) now lives nested under the Default Agent → Claude row in Agent → General, rendered with the new `InterfaceToggle` component. The picker only shows when Claude is the selected default agent (Codex has no Chat-mode equivalent). - Chat-specific config (default permission mode for new chats, auto-sleep idle minutes, chat density) moves to a `Chat interface` card under Agent → Claude — alongside the Claude command, env vars, etc. `settings.jsonModeClaudeTabs` removed entirely (11 call sites, under the spec's 10-site threshold but functionally a pure gate that no longer has a "behind-a-flag" reason to exist). Default behavior is now "Chat is always available; Terminal is still the default." Persistence and IPC handler dropped along with the field; existing configs with the key set are harmlessly ignored. `defaultClaudeTabType` field stays unchanged — values continue to be `'xterm' | 'json'` (no churn) but Settings now labels them `Terminal` and `Chat`. Onboarding: - New `choose-interface` QuestStep, inserted between `hidden` and `spawn-second`. The QuestCard renders the same `InterfaceToggle` the Settings panel uses (size="compact"), with a Continue button that advances to `spawn-second`. Skip / dismiss defaults to Terminal (the existing `defaultClaudeTabType` default). Per-tab switch chip: - Every Claude tab header (agent.claude + json-claude) gets a small icon button (MessageSquare for Chat-bound switch, TerminalIcon for Terminal-bound) right before the close button, with a `Switch to Chat` / `Switch to Terminal` tooltip. Wires into the existing `convertTabType` IPC — no new plumbing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…erminal body
The per-tab icon chip felt cramped and easy to miss. The new affordance
overlays the Terminal Claude tab itself (top-left, mirroring the
top-right Spectating/Take-control overlay): a Sparkles icon plus
"Switch to the new Chat mode" — a discoverable nudge rather than a
generic toggle.
- TerminalPanel: drop the per-tab MessageSquare/TerminalIcon chip.
- XTerminal: new optional `onSwitchToChat` prop renders the chip
when set, the tab is a Claude agent, and the terminal isn't
loading/exited.
- WorkspaceView: thread `onSwitchToChat` through, wired to the
existing `convertTabType('json-claude')` IPC for Claude agent
tabs.
The reverse direction (Chat → Terminal) is still reachable via the
tab's right-click menu and the Settings interface picker. No need
to clutter the Chat body since Chat doesn't need promotion.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There's no real cost meter UI in Chat — the description was forward- looking and read oddly to users. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…hat tabs
The Terminal-tab Chat promo chip now ships with an X button that
persistently hides the nudge across the workspace. Once dismissed,
the user keeps Settings → Agent → Interface and right-click → Switch
to Chat as the discovery surfaces.
New `settings.chatPromotionDismissed: boolean` slice field (5-file
pattern: shared slice + test, persistence, initial-state, IPC,
backend method, type). Defaults to false.
On Chat tabs, when the user's default is still Terminal (i.e. they
transitioned from Terminal → Chat on this tab), a top-left overlay
shows two buttons:
- "Switch back" — calls `panesConvertTabType('agent')` to revert
this tab to a Terminal Claude tab.
- "Set Chat as default" — calls `setDefaultClaudeTabType('json')`.
Both overlay buttons auto-hide afterwards since the user is now
at home in Chat.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- "Switch back" → "Switch back to Terminal mode" - "Set Chat as default" → "Make Chat mode default" - Tooltips on the Switch-to-Chat, X dismiss, and Switch-back buttons point users at the right-click tab menu as a permanent alternative. - Tooltip on the Make-Chat-default button points at Settings → Agent → Interface for reversing the choice later. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sends `app:debugResetOnboarding` from the Help menu (gated on `!app.isPackaged`) and the renderer flips the quest back to 'hidden'. The choose-interface card resurfaces on the next worktree tick. Lets us re-test the onboarding flow without nuking `userData/config.json`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Big brand-gradient "What are we going to build today?" with a Sparkles-in-a-gradient-circle above it, vertically centered in the scroll area when the chat has no entries / pending approvals / busy indicator. Subtitle "Send a message to get started." in muted text. Hidden the moment the first entry lands. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bare "Switch to Terminal" / "Switch to Chat" reads ambiguously (Terminal what? Chat what?). Adding "mode" makes the right-click menu, the sparkles button tooltip, and the Settings Interface radio match the overlay copy already in place. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The empty-state hero (`min-h-full`) and the regular `px-4 py-3 space-y-3` content wrapper were both rendering when entries were empty. The wrapper added ~24px of padding below the full-height empty state, producing a tiny scrollable overflow. Switch to a ternary so only one of the two trees mounts at a time. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…in place Repurposes the dev menu entry I added earlier. Instead of resetting the QuestCard, it toggles a renderer-local override that forces the 4-step welcome / onboarding form to render even when repos are already added, so the layout can be inspected without wiping userData. A warning-tinted banner inside the form makes it obvious we're in preview mode and offers an Exit preview button (toggling the menu item again also exits). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 4-step welcome form's "Choose your default agent" step now reveals the Terminal/Chat InterfaceToggle right below the Claude button when Claude is the selected default — same nested visual pattern as Settings → Agent. Skipping it leaves the existing 'xterm' default in place. Drops the post-creation QuestCard 'choose-interface' step now that the welcome form covers it. QuestStep union goes back to the original 5 values (hidden → spawn-second → switch-between → finale → done). QuestCard reverts to its pre-PR shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Subtle "Setting"-section flourish to draw the eye to the recently- promoted Chat interface inside the Terminal/Chat radio. Uses the same brand-gradient-bg as the Sparkles overlay button and onboarding finale CTA for visual consistency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promotes the React-chat interface for Claude tabs from its experimental name. Renames user-facing strings, restructures Settings so the interface choice nests under the Default Agent, threads the picker into onboarding, and adds discoverable in-tab switch affordances. Internal identifiers (
json-claude,JsonModeChat,jsonClaude/*events,defaultClaudeTabType: 'xterm' | 'json') stay unchanged. Default for new installs is still Terminal — this is promotion via visibility, not a default flip.What's new for users
InterfaceTogglecomponent). The standalone Experimental "JSON-mode Claude tabs" sub-card is gone; Chat-specific behavior (permission mode, auto-sleep, density) moves into aChat interfacecard under Agent → Claude.choose-interfacestep sits betweenhiddenandspawn-second, renders the sameInterfaceTogglewith a Continue button. Skipping defaults to Terminal.✨ Switch to the new Chat modechip (sibling of the existing Spectating/Take control affordance), with an X dismiss button that persistently hides the promo viasettings.chatPromotionDismissed. Tooltip on both buttons points users at the right-click tab menu.Switch back to Terminal mode+Make Chat mode defaultbuttons. Both auto-hide once Chat becomes the default. Tooltips point at right-click menu and Settings respectively.What's removed
settings.jsonModeClaudeTabsflag and all of its gates. Chat is always available now; default behavior is unchanged for users on the oldfalsedefault (Terminal stays default).Dev affordances
!app.isPackaged): toggles a renderer-local override that forces the 4-step welcome form to render even when repos are added. Shows a "Preview mode" banner with an Exit button inside the form.Test plan
npm run typecheckcleannpx electron-vite buildcleannpx vitest run src/shared— 582 tests passing (settings slice, onboarding slice, terminals slice tests cover the rename + new field)userData/config.json, run through onboarding, confirm choose-interface card appears after first worktree-add.🤖 Generated with Claude Code